package com.oos.zone.wechat.cp.service.handler;

import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import me.chanjar.weixin.cp.api.WxCpExternalContactService;
import me.chanjar.weixin.cp.api.WxCpMediaService;
import me.chanjar.weixin.cp.api.WxCpMessageService;
import me.chanjar.weixin.cp.api.WxCpUserService;
import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
import me.chanjar.weixin.cp.bean.article.NewArticle;
import me.chanjar.weixin.cp.bean.external.contact.WxCpExternalContactBatchInfo;
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult;
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
import me.chanjar.weixin.cp.bean.messagebuilder.*;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 功能描述：
 *
 * @author 拓金辉
 * @version 1.0
 * @date 2022-01-20 17:34:30
 */
@Log4j2
@Service
public class WxCpEnterAgentMessageHandler extends AbstractWxCpMessageHandler {

    @Override
    @SneakyThrows
    public WxCpXmlOutMessage doHandle() {

        final WxCpExternalContactService wxCpExternalContactService = wxCpService.getExternalContactService();
        final WxCpUserService wxCpUserService = wxCpService.getUserService();
        final WxCpMessageService wxCpMessageService = wxCpService.getMessageService();
        final WxCpMediaService wxCpMediaService = wxCpService.getMediaService();

        final List<String> followerUserIds = wxCpExternalContactService.listFollowers();

        if (!ObjectUtils.isEmpty(followerUserIds)) {
            final String[] userIds = followerUserIds.toArray(new String[0]);
            final List<WxCpExternalContactBatchInfo.ExternalContactInfo> externalContactInfos = this._contactDetailBatch(wxCpExternalContactService, userIds);
            System.out.println(externalContactInfos);
        }

        final Integer agentId = wxMessage.getAgentId();
        final String toUser = wxMessage.getFromUserName();

        if (false) {

            final TextBuilder textBuilder = WxCpMessage.TEXT().agentId(agentId).toUser("wmmVt9DAAAutG11nASe8Ic95AbewlzKA");
            textBuilder.content("你的快递已到，请携带工卡前往邮件中心领取。\\n出发前可查看<a href=\\\"http://work.weixin.qq.com\\\">邮件中心视频实况</a>，聪明避开排队。");
            final WxCpMessage wxCpMessage = textBuilder.build();
            final WxCpMessageSendResult wxCpMessageSendResult = this._asyncSend(wxCpMessageService, wxCpMessage);
        }

        if (false) {
            final WxCpMessage wxCpMessage1 = this.textMessage(agentId, toUser);
            final WxCpMessage wxCpMessage2 = this.imageMessage(agentId, toUser);
            final WxCpMessage wxCpMessage3 = this.voiceMessage(agentId, toUser);
            final WxCpMessage wxCpMessage4 = this.videoMessage(agentId, toUser);
            final WxCpMessage wxCpMessage5 = this.fileMessage(agentId, toUser);
            final WxCpMessage wxCpMessage6 = this.textCardMessage(agentId, toUser);
            final WxCpMessage wxCpMessage7 = this.newsMessage(agentId, toUser);
            final WxCpMessage wxCpMessage8 = this.mpnewsMessage(agentId, toUser);
            final WxCpMessage wxCpMessage9 = this.markdownMessage(agentId, toUser);
            final WxCpMessage wxCpMessage10 = this.miniProgramNoticeMessage(agentId, toUser);

            final List<WxCpMessage> wxCpMessages = Arrays.asList(
                    wxCpMessage1, wxCpMessage2, wxCpMessage3,
                    wxCpMessage4, wxCpMessage5, wxCpMessage6,
                    wxCpMessage7, wxCpMessage8, wxCpMessage9,
                    wxCpMessage10);
            wxCpMessages.forEach(wxCpMessage -> CompletableFuture.runAsync(() -> this._asyncSend(wxCpMessageService, wxCpMessage), executor));
        }

        CompletableFuture.runAsync(() -> log.info("进入应用事件"), executor);
        return defaultTextMessage;
    }

    public List<WxCpExternalContactBatchInfo.ExternalContactInfo> _contactDetailBatch(WxCpExternalContactService wxCpExternalContactService, String[] userIds) {
        try {
            AtomicReference<List<WxCpExternalContactBatchInfo.ExternalContactInfo>> atomicReference = new AtomicReference<>(Collections.emptyList());
            String nextCursor = null;

            do {
                final WxCpExternalContactBatchInfo contactDetailBatch = wxCpExternalContactService.getContactDetailBatch(userIds, nextCursor, 100);
                final List<WxCpExternalContactBatchInfo.ExternalContactInfo> collect = contactDetailBatch.getExternalContactList();
                nextCursor = contactDetailBatch.getNextCursor();
                atomicReference.set(Stream.concat(atomicReference.get().stream(), Optional.ofNullable(collect).orElseGet(Collections::emptyList).stream()).collect(Collectors.toList()));
            } while (nextCursor != null && !nextCursor.isEmpty());

            return atomicReference.get();
        } catch (Exception e) {
            log.error(e);
            throw new RuntimeException(e);
        }
    }

    private WxCpMessageSendResult _asyncSend(WxCpMessageService wxCpMessageService, WxCpMessage wxCpMessage) {
        try {
            return wxCpMessageService.send(wxCpMessage);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // 文本消息
    public WxCpMessage textMessage(Integer agentId, String toUser) {
        final TextBuilder textBuilder = WxCpMessage.TEXT().agentId(agentId).toUser(toUser);
        textBuilder.content("你的快递已到，请携带工卡前往邮件中心领取。\\n出发前可查看<a href=\\\"http://work.weixin.qq.com\\\">邮件中心视频实况</a>，聪明避开排队。");
        return textBuilder.build();
    }

    // 图片消息
    public WxCpMessage imageMessage(Integer agentId, String toUser) {
        final ImageBuilder imageBuilder = WxCpMessage.IMAGE().agentId(agentId).toUser(toUser);
        imageBuilder.mediaId("MEDIA_ID");
        return imageBuilder.build();
    }

    // 语音消息
    public WxCpMessage voiceMessage(Integer agentId, String toUser) {
        final VoiceBuilder voiceBuilder = WxCpMessage.VOICE().agentId(agentId).toUser(toUser);
        voiceBuilder.mediaId("MEDIA_ID");
        return voiceBuilder.build();
    }

    // 视频消息
    public WxCpMessage videoMessage(Integer agentId, String toUser) {
        final VideoBuilder videoBuilder = WxCpMessage.VIDEO().agentId(agentId).toUser(toUser);
        videoBuilder.mediaId("MEDIA_ID").title("Title").description("Description");
        return videoBuilder.build();
    }

    // 文件消息
    public WxCpMessage fileMessage(Integer agentId, String toUser) {
        final FileBuilder fileBuilder = WxCpMessage.FILE().agentId(agentId).toUser(toUser);
        fileBuilder.mediaId("1Yv-zXfHjSjU-7LH-GwtYqDGS-zz6w22KmWAT5COgP7o");
        return fileBuilder.build();
    }

    // 文本卡片消息
    public WxCpMessage textCardMessage(Integer agentId, String toUser) {
        final TextCardBuilder textCardBuilder = WxCpMessage.TEXTCARD().agentId(agentId).toUser(toUser);
        textCardBuilder
                .title("领奖通知")
                .description("<div class=\\\"gray\\\">2016年9月26日</div> <div class=\\\"normal\\\">恭喜你抽中iPhone 7一台，领奖码：xxxx</div><div class=\\\"highlight\\\">请于2016年10月10日前联系行政同事领取</div>")
                .url("www.baidu.com")
                .btnTxt("更多");
        return textCardBuilder.build();
    }

    // 图文消息
    public WxCpMessage newsMessage(Integer agentId, String toUser) {
        final NewsBuilder newsBuilder = WxCpMessage.NEWS().agentId(agentId).toUser(toUser);

        NewArticle newArticle = new NewArticle();
        newArticle.setTitle("中秋节礼品领取");
        newArticle.setDescription("今年中秋节公司有豪礼相送");
        newArticle.setUrl("URL");
        newArticle.setPicUrl("http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png");
        newArticle.setBtnText("更多");

        newsBuilder.addArticle(newArticle);
        return newsBuilder.build();
    }

    // 图文消息（mpnews）
    public WxCpMessage mpnewsMessage(Integer agentId, String toUser) {
        final MpnewsBuilder mpnewsBuilder = WxCpMessage.MPNEWS().agentId(agentId).toUser(toUser);

        MpnewsArticle mpnewsArticle = new MpnewsArticle();
        mpnewsArticle.setTitle("Title");
        mpnewsArticle.setThumbMediaId("MEDIA_ID");
        mpnewsArticle.setAuthor("Author");
        mpnewsArticle.setContentSourceUrl("URL");
        mpnewsArticle.setContent("Content");
        mpnewsArticle.setDigest("Digest description");

        mpnewsBuilder.addArticle(mpnewsArticle);
        return mpnewsBuilder.build();
    }

    // markdown消息
    public WxCpMessage markdownMessage(Integer agentId, String toUser) {
        final MarkdownMsgBuilder markdownMsgBuilder = WxCpMessage.MARKDOWN().agentId(agentId).toUser(toUser);
        markdownMsgBuilder.content("您的会议室已经预定，稍后会同步到`邮箱`\n" +
                "\t\t\t\t>**事项详情**\n" +
                "\t\t\t\t>事　项：<font color=\\\"info\\\">开会</font>\n" +
                "\t\t\t\t>组织者：@miglioguan\n" +
                "\t\t\t\t>参与者：@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang\n" +
                "\t\t\t\t>\n" +
                "\t\t\t\t>会议室：<font color=\\\"info\\\">广州TIT 1楼 301</font>\n" +
                "\t\t\t\t>日　期：<font color=\\\"warning\\\">2018年5月18日</font>\n" +
                "\t\t\t\t>时　间：<font color=\\\"comment\\\">上午9:00-11:00</font>\n" +
                "\t\t\t\t>\n" +
                "\t\t\t\t>请准时参加会议。\n" +
                "\t\t\t\t>\n" +
                "\t\t\t\t>如需修改会议信息，请点击：[修改会议信息](https://work.weixin.qq.com)");
        return markdownMsgBuilder.build();
    }

    // 小程序通知消息
    public WxCpMessage miniProgramNoticeMessage(Integer agentId, String toUser) {
        final MiniProgramNoticeMsgBuilder miniProgramNoticeMsgBuilder = WxCpMessage.newMiniProgramNoticeBuilder().agentId(agentId).toUser(toUser);
        miniProgramNoticeMsgBuilder
                .appId("wx123123123123123")
                .page("pages/index?userid=zhangsan&orderid=123123123")
                .title("会议室预订成功通知")
                .description("4月27日 16:16")
                .emphasisFirstItem(Boolean.TRUE)
                .contentItems(Collections.singletonMap("会议室", "402"));
        return miniProgramNoticeMsgBuilder.build();
    }


    private InputStream _inputStream(String url) {
        try {
            URL URL = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) URL.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(20 * 1000);
            return new BufferedInputStream(conn.getInputStream());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
